package com.spyx.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.atyx.spyx.enums.PaymentType;
import com.atyx.spyx.model.order.PaymentInfo;
import com.atyx.spyx.vo.user.UserLoginVo;
import com.github.wxpay.sdk.WXPayUtil;
import com.spyx.payment.service.PaymentInfoService;
import com.spyx.payment.service.WeiXinService;
import com.spyx.payment.util.ConstantPropertiesUtils;
import com.spyx.payment.util.HttpClient;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class WeiXinServiceImpl implements WeiXinService {
    @Autowired
    private PaymentInfoService paymentInfoService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public Map<String, String> createJsapi(String orderNo) throws Exception {
        //1.给payment_info表中添加数据(目的:表示某个订单正在支付)
        //1.1 需要先校验传过来的orderNo是否正在支付-先根据orderNo查询数据库
       PaymentInfo paymentInfo=paymentInfoService.getPaymentInfoByOrderNo(orderNo,PaymentType.WEIXIN);
       //1.2 判断结果是否为空
        if(paymentInfo==null){
            //保存订单数据到数据库
            paymentInfo = paymentInfoService.savePaymentInfo(orderNo, PaymentType.WEIXIN);
        }
        //2.封装微信支付系统接口所需要的参数-参数的key是官网已经定义好的，value值需要根据具体项目编写
        Map paramMap=new HashMap();
        //设置参数
        paramMap.put("appid", ConstantPropertiesUtils.APPID);  //支付的appid
        paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);//partnerKey
        paramMap.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
        paramMap.put("body", paymentInfo.getSubject());//交易内容
        paramMap.put("out_trade_no", paymentInfo.getOrderNo()); //订单编号
        int totalFee = paymentInfo.getTotalAmount().multiply(new BigDecimal(100)).intValue();
        paramMap.put("total_fee", String.valueOf(totalFee));//支付金额
        paramMap.put("spbill_create_ip", "127.0.0.1");
        paramMap.put("notify_url", ConstantPropertiesUtils.NOTIFYURL); //回调地址
        paramMap.put("trade_type", "JSAPI"); //支付类型
//			paramMap.put("openid", "o1R-t5trto9c5sdYt6l1ncGmY5iY");
        UserLoginVo userLoginVo = (UserLoginVo)redisTemplate.opsForValue().get("user:login:" + paymentInfo.getUserId());
        if(null != userLoginVo && !StringUtils.isEmpty(userLoginVo.getOpenId())) {
            paramMap.put("openid", userLoginVo.getOpenId());
        } else {
            paramMap.put("openid", "oD7av4igt-00GI8PqsIlg5FROYnI");
        }
        //3.发送请求到微信服务端(腾讯),获取预付单
        HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
        //3.1 绑定参数
        httpClient.setXmlParam(WXPayUtil.generateSignedXml(paramMap,ConstantPropertiesUtils.PARTNERKEY));
        //3.2 设置支持https请求
        httpClient.setHttps(true);  //http https
        //3.3 发送请求
        httpClient.post();

        //4.获取支付接口返回的内容
        String content = httpClient.getContent();
        //4.1 将返回的xml内容转换成map集合
        Map<String, String> xmlToMap = WXPayUtil.xmlToMap(content);
        System.out.println("微信下单时返回的数据:"+ JSON.toJSONString(xmlToMap));

        //5.封装数据,为了获取paySign的值(包含预付单标识值)
        Map<String, String> parameterMap = new HashMap<>();
        String prepayId = String.valueOf(xmlToMap.get("prepay_id"));
        String packages = "prepay_id=" + prepayId;
        parameterMap.put("appId", ConstantPropertiesUtils.APPID); //绑定appid
        parameterMap.put("nonceStr", xmlToMap.get("nonce_str"));//随机字符串
        parameterMap.put("package", packages);//订单详情扩展字符串
        parameterMap.put("signType", "MD5"); //加密方式
        parameterMap.put("timeStamp", String.valueOf(new Date().getTime()));//时间戳
        //根据上面的map中绑定的数据，生成签名(paySign)
        String paySign = WXPayUtil.generateSignature(parameterMap, ConstantPropertiesUtils.PARTNERKEY);

        //6.返回预付单结果-将二维码包含的数据返回给前端
        Map<String, String> result = new HashMap();
        result.put("timeStamp", parameterMap.get("timeStamp"));
        result.put("nonceStr", parameterMap.get("nonceStr"));
        result.put("signType", "MD5");
        result.put("paySign", paySign);
        result.put("package", packages);
        if(null != xmlToMap.get("result_code")) {
            //微信支付二维码2小时过期，可采取2小时未支付取消订单
            redisTemplate.opsForValue().set(orderNo, result, 120, TimeUnit.MINUTES);
        }
        return result;
    }

    @Override
    public Map queryPayStatus(String orderNo, String name) {
        try {
            //1.封装查询支付状态时的参数
            Map paramMap=new HashMap();
            paramMap.put("appid", ConstantPropertiesUtils.APPID);//appid
            paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);//partner的值
            paramMap.put("out_trade_no", orderNo); //交易编号
            paramMap.put("nonce_str", WXPayUtil.generateNonceStr()); //随机值
            //2.发送查询请求
            HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
            httpClient.setXmlParam(WXPayUtil.generateSignedXml(paramMap,ConstantPropertiesUtils.PARTNERKEY));
            httpClient.setHttps(true);
            httpClient.post();
            //3.获取微信服务端返回的结果
            String content = httpClient.getContent();
            Map<String, String> xmlToMap = WXPayUtil.xmlToMap(content);
            //4.返回
            return xmlToMap;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
}
